package com.advert.boot.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.advert.boot.common.constant.Constants;
import com.advert.boot.common.exception.BusinessException;
import com.advert.boot.common.result.ResultCode;
import com.advert.boot.common.util.FileMD5Utils;
import com.advert.boot.system.mapper.AdvertFilesMapper;
import com.advert.boot.system.model.entity.AdvertFiles;
import com.advert.boot.system.service.AdvertFileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
@Slf4j
public class AdvertFileServiceImpl implements AdvertFileService {
    private final AdvertFilesMapper advertFilesMapper;
    @Value("${spring.servlet.multipart.location}")
    private String uploadAddress;


    @Override
    public Long storeFile(MultipartFile file) {
        String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));

        //效验文件的类型： png/pdf/jpg/bmp/jpeg
        String suffix = StrUtil.isNotBlank(fileName) ? FilenameUtils.getExtension(fileName) : null;
        if (StrUtil.isBlank(suffix) || (!StrUtil.isBlank(suffix) && !Constants.IMAGE_PDF.equalsIgnoreCase(suffix) &&
                !Constants.IMAGE_JPG.equalsIgnoreCase(suffix) && !Constants.IMAGE_PNG.equalsIgnoreCase(suffix) &&
                !Constants.IMAGE_JPEG.equalsIgnoreCase(suffix) && !Constants.IMAGE_BMP.equalsIgnoreCase(suffix))) {
            throw new UsernameNotFoundException("文件格式不支持！");
        }

        try {
            String filePath = uploadAddress + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
            File targetFile = new File(filePath);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }

            //构建上传文件的目标路径
            java.nio.file.Path path = Paths.get(filePath, System.currentTimeMillis() + "-" + fileName);
            //将上传的文件保存到目标路径
            //Files.copy(file.getInputStream(), path);

            //建立数据通道
            InputStream fileInputStream = file.getInputStream();
            FileOutputStream fileOutputStream = new FileOutputStream(path.toFile());
            //建立缓冲字节数组，边读边写
            byte[] buf = new byte[1024 * 10];
            int length; //用于记录每次读取的字节个数
            while ((length = fileInputStream.read(buf)) != -1) {
                fileOutputStream.write(buf, 0, length);
            }
            //关闭资源(关闭资源的原则：先开后关，后开先关)
            fileOutputStream.close();
            fileInputStream.close();

            AdvertFiles fileEntity = new AdvertFiles();
            fileEntity.setFileName(fileName);
            fileEntity.setFileType(file.getContentType());
            //fileEntity.setData(file.getBytes());
            fileEntity.setFilePath(path.toString());
            fileEntity.setFileSize(FileMD5Utils.convertToKB(file.getSize())/*(double) (file.getSize() / (1024 * 1024))*/); //转为MB
            advertFilesMapper.insert(fileEntity);

            return fileEntity.getId();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0L;
    }

    @Override
    public AdvertFiles getFile(Long fileId) {
        return advertFilesMapper.selectById(fileId);
    }

    @Override
    public void deleteFiles(List<Long> fileIds) {
        if (CollUtil.isEmpty(fileIds)) {
            throw new BusinessException(ResultCode.FAILED, "请选择数据！");
        }

        //删除存储的文件
        List<AdvertFiles> advertFiles = advertFilesMapper.selectBatchIds(fileIds);
        advertFiles.forEach(advertFile -> {
            if (StrUtil.isBlank(advertFile.getFilePath())) {
                return;
            }

            try {
                Files.deleteIfExists(Paths.get(advertFile.getFilePath()));
            } catch (IOException e) {
                log.error("删除服务器中的文件Error，文件路径：{}，异常信息：{}", advertFile.getFilePath(), e);
            }
        });

        //删除数据库中文件
        advertFilesMapper.deleteBatchIds(fileIds);
    }
}
